package org.django4j;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * ControllerInvoker执行对controller实例特定方法的调用。如果一个controller的方法希望被
 * ControllerInvoker调用，那么它必须满足以下条件：
 * <ul><li>
 * 该方法必须至少有两个参数，并且前面两个参数必须是{@link javax.servlet.http.HttpServletRequest}
 * 和{@link javax.servlet.http.HttpServletResponse}。比如UserController.getUser(request,response..)
 * </li>
 * <li>
 * 方法支持任意多的其他参数，这些参数只能从第三个参数开始指定，并且只能是int,String等原型类型. 
 * (autobox,因此不需要做参数类型转换)。
 * 这些参数也必须按照顺序指定，这个顺序和url正则表达式指定的参数组是对应的。假设^/user/(\d+)/$
 * 映射到UserController的getUser方法，那么getUser的参数必须为(HttpServletRequest request,
 * HttpServletResponse response, int userID)的形式。框架会自动从url中提取(\d+)为userID，
 * 并且在调用controller方法的时候，将从url中获取的参数值按照顺序设置到args[]中。
 * 方法的返回值必须是{@link org.django4j.Model}类型。
 * </li></ul>
 */
public interface ControllerInvoker {
    
    /**
     * 调用controller的特定方法。django4j会映射一个请求到controller的特定方法，并且可以从url中
     * 获得调用方法的参数（通过正则表达式的组来实现）。
     * @param request       http servlet request.
     * @param response      http servlet response.
     * @param controller    the controller which map to a specific request url.
     * @param method        the controller method which map to a specific request url.
     * @param args          根据正则表达式从url中提取出的方法调用参数（不包括request,response）.
     * @return
     */
    public Model invoke(HttpServletRequest request, HttpServletResponse response, 
            Object controller, Method method, Object[] args);
}
